package com.whc.gulimall.product.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.whc.common.constant.AttrSearchTypeConstant;
import com.whc.common.constant.ProductConstant;
import com.whc.common.to.SkuHasStockVo;
import com.whc.common.to.SkuReductionTo;
import com.whc.common.to.SpuBoundTo;
import com.whc.common.to.es.SkuEsModel;
import com.whc.common.utils.PageUtils;
import com.whc.common.utils.Query;
import com.whc.common.utils.R;
import com.whc.gulimall.product.dao.SpuInfoDao;
import com.whc.gulimall.product.entity.*;
import com.whc.gulimall.product.feign.CouponFeignService;
import com.whc.gulimall.product.feign.SearchFeignService;
import com.whc.gulimall.product.feign.WareFeignService;
import com.whc.gulimall.product.service.*;
import com.whc.gulimall.product.vo.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;


@Service("spuInfoService")
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoDao, SpuInfoEntity> implements SpuInfoService {

    /**
     * spu信息介绍 Service
     */
    @Resource
    private SpuInfoDescService spuInfoDescService;

    /**
     * spu图片 Service
     */
    @Resource
    private SpuImagesService spuImagesService;

    /**
     * spu属性值 Service
     */
    @Resource
    private ProductAttrValueService productAttrValueService;

    /**
     * 商品属性 Service
     */
    @Resource
    private AttrService attrService;

    /**
     * sku图片
     */
    @Resource
    private SkuImagesService skuImagesService;

    /**
     * sku销售属性&值 Service
     */
    @Resource
    private SkuSaleAttrValueService skuSaleAttrValueService;

    /**
     * sku信息 Service
     */
    @Resource
    private SkuInfoService skuInfoService;

    /**
     * CouponFeignService
     */
    @Resource
    private CouponFeignService couponFeignService;

    /**
     * WareFeignService
     */
    @Resource
    private WareFeignService wareFeignService;

    /**
     * SearchFeignService
     */
    @Resource
    private SearchFeignService searchFeignService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<SpuInfoEntity> queryWrapper = new QueryWrapper<>();
        // 查询条件
        String key = (String) params.get("key");
        if (StrUtil.isNotBlank(key)) {
            queryWrapper.and(w -> w.eq("id", key).or().like("spu_name", key));
        }

        // 上架还是下架
        String status = (String) params.get("status");
        if (StrUtil.isNotBlank(status)) {
            queryWrapper.eq("publish_status", status);
        }
        // 品牌id
        String brandId = (String) params.get("brandId");
        if (StrUtil.isNotBlank(brandId) && !"0".equals(brandId)) {
            queryWrapper.eq("brand_id", status);
        }
        // 分类id
        String catelogId = (String) params.get("catelogId");
        if (StrUtil.isNotBlank(catelogId) && !"0".equals(catelogId)) {
            queryWrapper.eq("catalog_id", catelogId);
        }

        IPage<SpuInfoEntity> page = this.page(new Query<SpuInfoEntity>().getPage(params), queryWrapper);

        return new PageUtils(page);
    }

    /**
     * 新增商品
     *
     * @param spuSaveVo 商品信息
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveSpu(SpuSaveVo spuSaveVo) {
        // 保存spu基本信息 pms_spu_info
        SpuInfoEntity spuInfoEntity = new SpuInfoEntity();
        BeanUtil.copyProperties(spuSaveVo, spuInfoEntity);
        save(spuInfoEntity);
        // 获取spuId
        Long spuId = spuInfoEntity.getId();

        // 保存spu的描述图片 pms_spu_info_desc
        List<String> decript = spuSaveVo.getDecript();
        String description = CharSequenceUtil.join(",", decript);
        spuInfoDescService.saveSpuInfoDesc(spuId, description);

        // 保存spu的图片集 pms_spu_images
        List<String> images = spuSaveVo.getImages();
        spuImagesService.saveImages(spuId, images);

        // 保存spu的规格参数 pms_product_attr_value
        List<BaseAttrs> baseAttrs = spuSaveVo.getBaseAttrs();

        List<Long> attrIds = baseAttrs.stream().map(BaseAttrs::getAttrId).collect(Collectors.toList());
        // 获取属性id集合
        List<AttrEntity> attrEntities = attrService.listByIds(attrIds);
        // 获取以attrId为Key，attrName为value
        Map<Long, String> attrMap = attrEntities.stream()
                .collect(Collectors.toMap(AttrEntity::getAttrId, AttrEntity::getAttrName));
        // 转换对象
        List<ProductAttrValueEntity> productAttrValueEntities = baseAttrs.stream().map(item -> {
            ProductAttrValueEntity productAttrValueEntity = new ProductAttrValueEntity();
            productAttrValueEntity.setSpuId(spuId);
            productAttrValueEntity.setAttrId(item.getAttrId());
            productAttrValueEntity.setAttrName(attrMap.get(item.getAttrId()));
            productAttrValueEntity.setAttrValue(item.getAttrValues());
            productAttrValueEntity.setQuickShow(item.getShowDesc());
            return productAttrValueEntity;
        }).collect(Collectors.toList());
        // 保存
        productAttrValueService.saveBatch(productAttrValueEntities);

        // 保存spu的积分信息 sms_spu_bounds
        Bounds bounds = spuSaveVo.getBounds();
        SpuBoundTo spuBoundTo = new SpuBoundTo();
        BeanUtil.copyProperties(bounds, spuBoundTo);
        R r = couponFeignService.saveSpuBounds(spuBoundTo);
        if (!r.getCode().equals(0)) {
            log.error("远程调用[couponFeignService.saveSpuBounds(spuBoundTo)]失败");
        }

        // 保存当前spu对应的所有sku信息
        List<Skus> skus = spuSaveVo.getSkus();
        for (Skus sku : skus) {
            // 获取默认图片
            List<Images> imagesList = sku.getImages();
            String defaultImgUrl = "";
            for (Images img : imagesList) {
                if (img.getDefaultImg() == 1) {
                    defaultImgUrl = img.getImgUrl();
                }
            }

            // sku的基本信息，pms_sku_info
            SkuInfoEntity skuInfoEntity = new SkuInfoEntity();
            BeanUtil.copyProperties(sku, skuInfoEntity);
            skuInfoEntity.setSpuId(spuId);
            skuInfoEntity.setSkuDesc("");
            skuInfoEntity.setCatalogId(spuSaveVo.getCatalogId());
            skuInfoEntity.setBrandId(spuSaveVo.getBrandId());
            skuInfoEntity.setSkuDefaultImg(defaultImgUrl);
            skuInfoEntity.setSaleCount(0L);
            skuInfoService.save(skuInfoEntity);

            // 获取到skuId
            Long skuId = skuInfoEntity.getSkuId();

            // 保存sku图片
            List<SkuImagesEntity> skuImagesEntities = imagesList.stream()
                    .filter(item -> StrUtil.isNotBlank(item.getImgUrl()))
                    .map(item -> {
                        SkuImagesEntity skuImagesEntity = new SkuImagesEntity();
                        skuImagesEntity.setSkuId(skuId);
                        BeanUtil.copyProperties(item, skuImagesEntity);
                        return skuImagesEntity;
                    }).collect(Collectors.toList());
            skuImagesService.saveBatch(skuImagesEntities);

            // 保存sku销售属性&值
            List<Attr> attr = sku.getAttr();
            List<SkuSaleAttrValueEntity> skuSaleAttrValueEntities = attr.stream().map(item -> {
                SkuSaleAttrValueEntity saleAttrValueEntity = new SkuSaleAttrValueEntity();
                BeanUtil.copyProperties(item, saleAttrValueEntity);
                saleAttrValueEntity.setSkuId(skuId);
                return saleAttrValueEntity;
            }).collect(Collectors.toList());
            skuSaleAttrValueService.saveBatch(skuSaleAttrValueEntities);

            // 保存sku的优惠、满减等信息
            SkuReductionTo skuReductionTo = new SkuReductionTo();
            skuReductionTo.setSkuId(skuId);
            BeanUtil.copyProperties(sku, skuReductionTo);
            if (skuReductionTo.getFullCount() > 0 || skuReductionTo.getFullPrice().compareTo(BigDecimal.ZERO) > 0) {
                r = couponFeignService.saveSkuReduction(skuReductionTo);
                if (!r.getCode().equals(0)) {
                    log.error("远程调用[couponFeignService.saveSkuReduction(skuReductionTo)]失败");
                }
            }

        }
    }

    /**
     * 上架商品
     *
     * @param spuId spuId
     */
    @Override
    public void upSpu(Long spuId) {
        // 根据spuId获取到SkuInfoEntities
        List<SkuInfoEntity> skuInfoEntities = skuInfoService.listBySpuId(spuId);
        // 判断是否有可上架的商品
        if (CollUtil.isNotEmpty(skuInfoEntities)) {
            // 通过spuId获取到attrValueEntities
            List<ProductAttrValueEntity> attrValueEntities = productAttrValueService.listAttrValueBySpuId(spuId);

            // 需要检索的属性
            List<SkuEsModel.Attr> attrs = null;

            // 上架商品需要有属性
            if (CollUtil.isNotEmpty(attrValueEntities)) {
                // 获取到属性id列表
                List<Long> attrIds = attrValueEntities.stream()
                        .map(ProductAttrValueEntity::getAttrId).collect(Collectors.toList());
                // 通过商品所拥有的属性id在pms_attr表中获取到可被检索的属性
                List<Long> searchAttrIds = attrService
                        .listSearchAttrIdsByAttrIds(attrIds, AttrSearchTypeConstant.SEARCH.getSearchType());

                // 过滤出可被检索的属性被进行转换
                Set<Long> finalAttrIds = new HashSet<>(searchAttrIds);
                attrs = attrValueEntities.stream()
                        .filter(item -> finalAttrIds.contains(item.getAttrId()))
                        .map(item -> {
                            SkuEsModel.Attr attr = new SkuEsModel.Attr();
                            BeanUtil.copyProperties(item, attr);
                            return attr;
                        })
                        .collect(Collectors.toList());
            }

            // 获取到skuIds
            List<Long> skuIds = skuInfoEntities.stream().map(SkuInfoEntity::getSkuId).collect(Collectors.toList());
            // 通过远程接口，获取到对应商品是否有库存
            R r = wareFeignService.hasStock(skuIds);
            // 转换为vo类
            List<SkuHasStockVo> skuHasStockVos = JSON.parseArray(JSON.toJSONString(r.get("data")), SkuHasStockVo.class);
            // 封装为map
            Map<Long, Integer> hasStockMap = skuHasStockVos.stream().filter(item -> item.getHasStock() != null)
                    .collect(Collectors.toMap(SkuHasStockVo::getSkuId, SkuHasStockVo::getHasStock));


            // 获取品牌信息
            BrandEntity brandEntity = this.getBrandBySpuId(spuId);
            List<SkuEsModel.Attr> finalAttrs = attrs;
            List<SkuEsModel> skuEsModelList = skuInfoEntities.stream().map(item -> {
                SkuEsModel skuEsModel = new SkuEsModel();
                // 属性对拷
                BeanUtil.copyProperties(item, skuEsModel);
                skuEsModel.setHasStock(!hasStockMap.get(skuEsModel.getSkuId()).equals(0));
                skuEsModel.setSkuPrice(item.getPrice());
                skuEsModel.setSkuImg(item.getSkuDefaultImg());
                skuEsModel.setAttrs(finalAttrs);
                skuEsModel.setBrandImg(brandEntity.getLogo());
                skuEsModel.setBrandName(brandEntity.getName());
                return skuEsModel;
            }).collect(Collectors.toList());

            // 上架商品
            R upStatusResult = searchFeignService.productStatusUp(skuEsModelList);
            // 上架成功
            if (upStatusResult.getCode().equals(0)) {
                // 修改spu发布状态
                baseMapper.updateSpuStatus(spuId, ProductConstant.SpuStatusEnum.SPU_UP.getCode());

                // 上架失败
            } else {

            }
        }
    }

    @Override
    public BrandEntity getBrandBySpuId(Long spuId) {
        return baseMapper.getBrandBySpuId(spuId);
    }

    /**
     * 通过skuId获取商品信息列表
     *
     * @param skuIds skuId列表
     * @return 商品信息列表
     */
    @Override
    public  Map<Long, ProductInfoVo> listProductInfos(List<Long> skuIds) {
        return baseMapper.listProductInfos(skuIds);
    }
}
